package com.pignest.hotel.system;

import java.util.Calendar;
import java.util.Date;

import com.pignest.hotel.beans.Living;
import com.pignest.hotel.beans.Room;
import com.pignest.hotel.definition.LivingState;
import com.pignest.hotel.definition.RoomLiveStatus;
import com.pignest.hotel.definition.RoomRepairStatus;
import com.pignest.hotel.definition.RoomUseStatus;
import com.pignest.hotel.spring.Services;
import com.pignest.hotel.util.DateUtil;

/**
 * 酒店的相关逻辑判断
 * */
public class Logic {
	
	/**
	 * 判断是否可以改变房间的使用状态, 没有变化视为不能改变
	 * */
	public static boolean canChangeStatus(Room room, RoomUseStatus status) {
		if (room == null || status == null)
			return false;
		RoomUseStatus s = RoomUseStatus.valueof(room.getUseStatus());
		if (s == null)
			return true;
		if (s == status)
			return false;
		switch (s) {
		case CLEAN:
			return status == RoomUseStatus.DIRTY || status == RoomUseStatus.EMPTY_NIGHT;
		case DIRTY:
			return status == RoomUseStatus.CLEAN || status == RoomUseStatus.CHECKING;
		case CHECKING:
			return status == RoomUseStatus.CLEAN || status == RoomUseStatus.DIRTY;
		case EMPTY_NIGHT:
			return status == RoomUseStatus.CLEAN || status == RoomUseStatus.CHECKING;
		}
		return true;
	}
	
	/**
	 * 判断是否可以改变房间的入住状态, 没有变化视为不能改变
	 * */
	public static boolean canChangeStatus(Room room, RoomLiveStatus status) {
		if (room == null || status == null)
			return false;
		RoomLiveStatus s = RoomLiveStatus.valueof(room.getLiveStatus());
		if (s == null)
			return true;
		if (s == status)
			return false;
		switch (s) {
		case EMPTY:
			return status == RoomLiveStatus.FILLED;
		case FILLED:
			return status == RoomLiveStatus.EMPTY;
		}
		return true;
	}
	
	/**
	 * 判断是否可以改变房间的入住状态, 没有变化视为不能改变
	 * */
	public static boolean canChangeStatus(Room room, RoomRepairStatus status) {
		if (room == null || status == null)
			return false;
		RoomRepairStatus s = RoomRepairStatus.valueof(room.getRepairStatus());
		if (s == null)
			return true;
		if (s == status)
			return false;
		switch (s) {
		case NORMAL:
			return status == RoomRepairStatus.REPAIR;
		case REPAIR:
			return status == RoomRepairStatus.NORMAL;
		}
		return true;
	}
	
	/** 
	 * 是否可以入住
	 * */
	public static boolean canLiving(Room room) {
		if (room == null)
			return false;
		if (RoomRepairStatus.REPAIR.is(room))
			return false;
		if (RoomLiveStatus.FILLED.is(room))
			return false;
		if (RoomUseStatus.CLEAN.is(room) || RoomUseStatus.EMPTY_NIGHT.is(room))
			return true;
		return false;
	}
	
	/**
	 * 是否可以退房
	 * 该房间必须 是已经入住的情况
	 * */
	public static boolean canCheckOut(Room room){
		if (room == null)
			return false;
//		if (RoomRepairStatus.REPAIR == RoomRepairStatus.valueof(room.getRepairStatus()))
//			return false;
		if (RoomLiveStatus.FILLED.is(room))
			return true;
		return false;
	}
	/**
	 * @id living id
	 * @return true 状态可以撤消
	 * **/
	 public static boolean isCancel(String id)
	    {
	    	Living l=Services.getReceptionService().get(Living.class, id);
	    	if(l.getLiveState().equals(LivingState.LIVING.name())){
	    		return true;
	    	}
	    	else 
	    		return false;
	    }
	 /**
	  * @param date l 入住时间
	  * @param date out 操作时间
	  * @return true 已超过 false 未超过
	  * 
	  * **/
	 public static boolean isExceedMinute(Date l,Date out)
	 {
		 if (l == null || out == null)
				return true;
		int m= getBetweenMinute(betweenSeconds(out, l));
		if(m>Config.getCancelLivingMinutes()){
			return true;
		}else
			return false;
	 }
	/**
	 * @param livingTime 入住时间
	 * @param leaveTime 退房时间
	 * @param member 是否会员(暂时没效果)
	 * 退房时计算是否要加收房费
	 * @return  0: 不加收
	 * 			1: 加收半天
	 * 			2: 加收一天
	 * 			3: 加收一天半
	 * 			4: 加收两天
	 * */
	public static int getLivingAdditionalTime(Date livingTime, Date leaveTime, boolean member) {
		if (livingTime == null || leaveTime == null)
			return 0;
		long oneday = DateUtil.ONE_DAY;
		long start = livingTime.getTime();		//开始入住
		long end = leaveTime.getTime();			//退房
		if (start >= end)
			return 0;
		int[] t = DateUtil.parseHMS(Config.getNightAuditTime());
		Calendar cal = Calendar.getInstance();
		cal.setTime(leaveTime);
		cal.set(Calendar.MILLISECOND, 0);
		
		cal.set(Calendar.HOUR_OF_DAY, t[0]);
		cal.set(Calendar.MINUTE, t[1]);
		cal.set(Calendar.SECOND, t[2]);
		long audit = cal.getTimeInMillis();		//今天夜审
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
//		long today = cal.getTimeInMillis();		//今天0时
		cal.set(Calendar.HOUR_OF_DAY, Config.getMorningTimePoint());
		long moring = cal.getTimeInMillis();	//早上
		cal.set(Calendar.HOUR_OF_DAY, Config.getNoonTimePoint());
		long noon = cal.getTimeInMillis();		//中午
		cal.set(Calendar.HOUR_OF_DAY, Config.getEveningTimePoint());
		long evening = cal.getTimeInMillis();	//夜晚
		if (noon <= moring || evening <= noon)
			throw new RuntimeException("time");
		if (!(audit < noon || audit > evening))
			throw new RuntimeException("audit");
		if (audit > evening)
			audit -= oneday;
		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(livingTime);
		cal2.set(Calendar.YEAR, cal.get(Calendar.YEAR));
		cal2.set(Calendar.MONTH, cal.get(Calendar.MONTH));
		cal2.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH));
		long tstart = cal2.getTimeInMillis();			//开始入住, 对应到今天的时间点
		
		int r = 0;
		if (tstart > audit && tstart < moring)	//在夜审之后, (早上)之前, 需要加收一天
			r += 2;
		if (end > evening)
			r += 2;
		else if (end > noon)
			r += 1;
		if (r == 1) {
			if (end - start < DateUtil.ONE_DAY)
				r = 2;		//最少入住一天
		}
		return r;
	}
	
	/**
	 * @see #getLivingAdditionalTime(Date, Date, boolean)
	 */
	public static int getLivingAdditionalTime(String livingTime, String leaveTime, boolean member) {
		Date living = DateUtil.toDate(livingTime, DateUtil.DEFAULT_DATETIME_FORMAT);
		Date leave = DateUtil.toDate(leaveTime, DateUtil.DEFAULT_DATETIME_FORMAT);
		return getLivingAdditionalTime(living, leave, member);
	}
	public static int betweenSeconds(Date date1,Date date2){
		   if(date1==null||date2==null)
			   return 0;
		   int i=(int)(date2.getTime()-date1.getTime())/(1000);
		   return i;
	   }
	   public static int getBetweenDay(int secondes){
		   return secondes/(24*60*60);      
	   }
	   public static int getBetweenHours(int secondes){
		   int nDay =getBetweenDay(secondes);
		   int nHour = (int)(secondes-nDay*24*60*60)/(60*60); 
	       return nHour;    
	   }
	   public static int getBetweenMinute(int secondes){
		   int nDay =getBetweenDay(secondes);
		   int nHour =getBetweenHours(secondes);
		   int nMinute = (int)(secondes-nDay*24*60*60-nHour*60*60)/60; 
		   return nMinute;
	   }
	   /**
	    * 计算结账时间与入住时间的显示时长
	    * **/
	   public static String getBetween(Date cDate,Date lDate)
	   {
		   if(lDate==null||cDate==null)
			   return "0天0小时0分钟";
		   int seconds =betweenSeconds(lDate,cDate);
		   int day =getBetweenDay(seconds);
		   int nHour =getBetweenHours(seconds);
		   int nMinute=getBetweenMinute(seconds);
		   String s = day+"天"+nHour+"小时"+nMinute+"分钟";
		   return s;
	   }
	   /**计算钟点房的单位数*/
	   public static int countUnionHours(Date cDate,Date lDate){
		   int hp=Config.getHourPeriod();//单位时长
		   int seconds =betweenSeconds(lDate,cDate);
		   int day =getBetweenDay(seconds);
		   int nHour =getBetweenHours(seconds);
		   //int nMinute=getBetweenMinute(seconds);
		   if(day==0)//当天的
		   {
			   if(nHour==0){
				   return 1;
			   }
			   if(nHour%hp==0){
				   return nHour/hp;
			   }else 
				   return nHour/hp+1;
		   }else{
			   return 8;
		   }
	   }
}
